#include "PointCloud.h"
#include <fstream>

GLOBAL_NAMESPACE_BEGIN

namespace MeshSpace
{
    PointCloud::PointCloud()
    {}

    PointCloud::~PointCloud()
    {}

    bool PointCloud::loadFromFile(const char* fileName)
    {
        FILE *m_pFile = fopen(fileName, "r");

        char *tok;
        char *tok_tok;
        char temp[128];

        std::vector<Vec3d> positions;
        std::vector<Color> colors;

        try
        {
            clearData();
            //read vertex
            fseek(m_pFile, 0, SEEK_SET);
            char pLine[512];

            while (fgets(pLine, 512, m_pFile))
            {
                if (pLine[0] == 'v' && pLine[1] == ' ')
                {
                    MATH::vector3d nvv;
                    tok = strtok(pLine, " ");
                    for (int i = 0; i < 3; i++)
                    {
                        tok = strtok(NULL, " ");
                        strcpy(temp, tok);
                        temp[strcspn(temp, " ")] = 0;
                        nvv[i] = (double)atof(temp);
                    }
                    positions.push_back(nvv);
                }
                else if (pLine[0] == 'v' && pLine[1] == 'c')
                {
                    Color col;
                    tok = strtok(pLine, " ");
                    for (int i = 0; i < 3; i++)
                    {
                        tok = strtok(NULL, " ");
                        strcpy(temp, tok);
                        temp[strcspn(temp, " ")] = 0;
                        col[i] = (double)atof(temp);
                    }
                    colors.push_back(col);
                }
            }
        }
        catch (...)
        {
            clearData();
            fclose(m_pFile);
            return false;
        }

        if (colors.empty())
        {
            for (size_t i = 0; i < positions.size(); i++)
            {
                insertPoint(positions[i]);
            }
        }
        else if (colors.size() == positions.size())
        {
            for (size_t i = 0; i < positions.size(); i++)
            {
                insertPoint(positions[i]);
                setPointColorAt(i, colors[i]);
            }
        }
        else
        {
            clearData();
            fclose(m_pFile);
            ZFW_EXCEPTION(Exception::ERR_INVALID_PARAMS, "File is occurpt.", "PointCloud::loadFromFile");
        }

        return !points_.empty();
    }

    void PointCloud::clearData()
    {
        points_.clear();
    }

    void PointCloud::insertPoint(const Vec3d& pos)
    {
        points_.push_back(PcPoint());
        points_.back().pos = pos;
    }

    bool PointCloud::checkIndexValid(int idx)
    {
        return idx >= 0 && idx < getPointSize();
    }

    int PointCloud::getPointSize()
    {
        return points_.size();
    }

    PcPoint PointCloud::getPointAt(int idx)
    {
        if (!checkIndexValid(idx)) return PcPoint();

        return points_[idx];
    }

    void PointCloud::setPointPositionAt(int idx, const Vec3d& pos)
    {
        if (!checkIndexValid(idx)) return;
        points_[idx].pos = pos;
    }

    void PointCloud::setPointColorAt(int idx, const Color& col)
    {
        if (!checkIndexValid(idx)) return;
        points_[idx].color = col;
    }
}

GLOBAL_NAMESPACE_END